using System;

namespace Extensions.RateLimiter.LeakyTokenBucket
{
    /// <summary>
    /// 令牌桶限流策略
    /// </summary>
    public class LeakyTokenBucketThrottleStrategy
    {
        /// <summary>
        /// 限制数量
        /// </summary>
        private readonly long _limitCount;

        /// <summary>
        /// 间隔秒数
        /// </summary>
        private readonly int _intervalNanoSeconds;

        /// <summary>
        /// 速度
        /// </summary>
        private readonly long _rate;

        /// <summary>
        /// 当前令牌数量
        /// </summary>
        private long _currentTokenCount;

        private long _lastTicks;

        public LeakyTokenBucketThrottleStrategy(long limitCount, int intervalNanoSeconds)
        {
            _limitCount = limitCount;
            _intervalNanoSeconds = intervalNanoSeconds;
            _lastTicks = DateTime.Now.Ticks;
        }

        public bool IsLimit(int n = 1)
        {
            var nowTicks = DateTime.Now.Ticks;

            _currentTokenCount = Math.Min(0, _currentTokenCount + (nowTicks - _lastTicks) * _rate);
            _lastTicks = nowTicks;
            if (_currentTokenCount < n)
            {
                return false;
            }

            _currentTokenCount -= n;
            return true;
        }
    }
}